use rand::{seq::SliceRandom, Rng};
use zxcvbn::zxcvbn;

const UPPER: &[u8] = b"ABCDEFGHJKLMNPQRSTUVWXYZ";
const LOWER: &[u8] = b"abcdefghijkmnpqrstuvwxyz";
const NUMBER: &[u8] = b"123456789";
const SYMBOL: &[u8] = b"!@#$%^&*_";

pub fn process_gen_pass(
    length: u8,
    upper: bool,
    lower: bool,
    number: bool,
    symbol: bool,
) -> anyhow::Result<String> {
    if length < 6 {
        return Err(anyhow::anyhow!(
            "The password must be at least 6 characters long."
        ));
    }

    let mut rng = rand::rng();
    let mut chars = Vec::new();

    let mut pass = Vec::new();

    if upper {
        chars.extend_from_slice(UPPER);

        let idx = rng.random_range(0..UPPER.len());
        pass.push(UPPER[idx]);
    }

    if lower {
        chars.extend_from_slice(LOWER);

        let idx = rng.random_range(0..LOWER.len());
        pass.push(LOWER[idx]);
    }

    if number {
        chars.extend(NUMBER);

        let idx = rng.random_range(0..NUMBER.len());
        pass.push(NUMBER[idx]);
    }

    if symbol {
        chars.extend_from_slice(SYMBOL);

        let idx = rng.random_range(0..SYMBOL.len());
        pass.push(SYMBOL[idx]);
    }

    for _ in 0..length - pass.len() as u8 {
        let idx = rng.random_range(0..chars.len());
        pass.push(chars[idx]);
    }

    pass.shuffle(&mut rng);

    let password = String::from_utf8(pass)?;

    //打印密码强度
    let estimate = zxcvbn(&password, &[]);
    eprintln!("password:{}, score {}", &password, estimate.score()); // 3

    Ok(password)
}
